pub struct Node<T> {
    element: T,
    next: Link<T>,
}
type Link<T> = Option<Box<Node<T>>>;
pub struct List<T> {
    head: Link<T>,
}
impl<T> List<T> {
    pub fn new() -> Self {
        List { head: None }
    }
    pub fn push(&mut self, item: T) {
        self.push_node(Box::new(Node {
            element: item,
            // 可变性与共享是互斥的，所以我们不能再改变head的同时使用head，
            // 或者在head数据缺失的情况下操纵head，
            // 所以这里用mem::replace()先剥离head的共享行为
            // 代码重构，上述描述已不准确
            next: None,
        }));
    }
    pub fn push_node(&mut self, mut node: Box<Node<T>>) {
        node.next = self.head.take();
        self.head = Some(node);
    }
    pub fn pop(&mut self) -> Option<T> {
        self.pop_node().map(|node| node.element)
    }
    pub fn pop_node(&mut self) -> Option<Box<Node<T>>> {
        self.head.take().map(|mut node| {
            self.head = node.next.take();
            node
        })
    }
    pub fn peek(&self) -> Option<&T> {
        self.head.as_ref().map(|node| &node.element)
    }
    pub fn peek_mut(&mut self) -> Option<&mut T> {
        self.head.as_mut().map(|node| &mut node.element)
    }
    pub fn iter_into(self) -> IterInto<T> {
        IterInto(self)
    }
    pub fn iter(&self) -> Iter<T> {
        Iter(self.head.as_deref())
    }
    pub fn iter_mut(&mut self) -> IterMut<T> {
        IterMut(self.head.as_deref_mut())
    }
}
impl<T> Drop for List<T> {
    fn drop(&mut self) {
        while let Some(h) = self.head.take() {
            self.head = h.next;
            //    println!("{:?}",h.element);
        }
    }
}
pub struct IterInto<T>(List<T>);
impl<T> Iterator for IterInto<T> {
    type Item = T;

    fn next(&mut self) -> Option<Self::Item> {
        self.0.pop()
    }
}
pub struct Iter<'a, T: 'a>(Option<&'a Node<T>>);
impl<'a, T> Iterator for Iter<'a, T> {
    type Item = &'a T;

    fn next(&mut self) -> Option<Self::Item> {
        // & is copy
        self.0.map(|current| {
            self.0 = current.next.as_deref();
            &current.element
        })
    }
}
pub struct IterMut<'a, T: 'a>(Option<&'a mut Node<T>>);
impl<'a, T> Iterator for IterMut<'a, T> {
    type Item = &'a mut T;

    fn next(&mut self) -> Option<Self::Item> {
        // &mut isn't Copy
        self.0.take().map(|current| {
            self.0 = current.next.as_deref_mut();
            &mut current.element
        })
    }
}
#[cfg(test)]
mod test {
    use super::List;

    #[test]
    fn basics() {
        let mut list: List<i32> = List::new();
        assert_eq!(list.pop(), None);
        list.push(1);
        list.push(2);
        list.push(3);
        assert_eq!(list.peek(), Some(&3));
        assert_eq!(list.peek_mut(), Some(&mut 3));
        // |&mut value| means "the argument is a mutable reference, but just copy the value it points to into value, please."
        list.peek_mut().map(|value| *value = 10);
        assert_eq!(list.peek(), Some(&10));
        assert_eq!(list.pop(), Some(10));
        assert_eq!(list.pop(), Some(2));
        assert_eq!(list.pop(), Some(1));
        assert_eq!(list.pop(), None);
    }
    #[test]
    fn iter_mut() {
        let mut list: List<i32> = List::new();
        list.push(1);
        list.push(2);
        list.push(3);
        list.push(4);
        for item in list.iter_mut() {
            *item += 1;
        }
        let mut iter = list.iter();
        assert_eq!(iter.next(), Some(&5));
        assert_eq!(iter.next(), Some(&4));
        assert_eq!(iter.next(), Some(&3));
        assert_eq!(iter.next(), Some(&2));
    }
    #[test]
    fn iter() {
        let mut list: List<i32> = List::new();
        list.push(1);
        list.push(2);
        list.push(3);
        list.push(4);
        let mut iter = list.iter();
        assert_eq!(iter.next(), Some(&4));
        assert_eq!(iter.next(), Some(&3));
        assert_eq!(iter.next(), Some(&2));
        assert_eq!(iter.next(), Some(&1));
    }
    #[test]
    fn iter_into() {
        let mut list: List<i32> = List::new();
        list.push(1);
        list.push(2);
        list.push(3);
        list.push(4);
        let mut iter = list.iter_into();
        assert_eq!(iter.next(), Some(4));
        assert_eq!(iter.next(), Some(3));
        assert_eq!(iter.next(), Some(2));
        assert_eq!(iter.next(), Some(1));
    }
}
